// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package cn.org.dbtools.star.stack.connector;

import cn.org.dbtools.star.stack.entity.ClusterInfoEntity;
import cn.org.dbtools.star.stack.exception.StarRequestException;
import cn.org.dbtools.star.stack.model.palo.StarResponseEntity;
import cn.org.dbtools.star.stack.rest.ResponseEntityBuilder;
import cn.org.dbtools.star.stack.util.CredsUtil;
import lombok.extern.slf4j.Slf4j;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.google.common.collect.Maps;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@Slf4j
public class StarForwardManagerClient extends StarClient {
    private static final String FE_MONITOR_CHECK_API = "/rest/v2/manager/monitor/value/node_num";

    protected HttpClientPoolManager poolManager;

    @Autowired
    public StarForwardManagerClient(HttpClientPoolManager poolManager) {
        this.poolManager = poolManager;
    }

    @Autowired
    private StarConfigClient starConfigClient;

    public Object forwardGet(String url, ClusterInfoEntity entity) throws Exception {
        log.debug("get request, url is {}.", url);

        Map<String, String> headers = Maps.newHashMap();
        setHeaders(headers);
        setAuthHeaders(headers, entity.getUser(), CredsUtil.tryAesDecrypt(entity.getPasswd()));
        StarResponseEntity response;
        try {
            response = poolManager.doGet(url, headers);
        } catch (JSONException e) {
            return ResponseEntityBuilder.notFound("not fount path");
        }
        if (response.getCode() != REQUEST_SUCCESS_CODE) {
            throw new StarRequestException("get exception:" + response.getData() + " url:" + url);
        }

        return ResponseEntityBuilder.ok(JSON.parse(response.getData()));
    }

    public Object forwardPost(String url, String requestBody, ClusterInfoEntity entity) throws Exception {
        log.debug("post request, url is {}.", url);

        Map<String, String> headers = Maps.newHashMap();
        setHeaders(headers);
        setAuthHeaders(headers, entity.getUser(), CredsUtil.tryAesDecrypt(entity.getPasswd()));
        headers.put("Content-Type", "application/json");
        StarResponseEntity response;
        try {
            response = poolManager.forwardPost(url, headers, requestBody);
        } catch (JSONException e) {
            return ResponseEntityBuilder.notFound("not fount path");
        }
        if (response.getCode() != REQUEST_SUCCESS_CODE) {
            throw new StarRequestException("post exception:" + response.getData());
        }
        return ResponseEntityBuilder.ok(JSON.parse(response.getData()));
    }

    public boolean doesFeMonitorExist(ClusterInfoEntity entity) throws Exception {
        String url = "http://" + entity.getAddress() + ":" + entity.getHttpPort() + FE_MONITOR_CHECK_API;
        Map<String, String> headers = Maps.newHashMap();
        setHeaders(headers);
        setAuthHeaders(headers, entity.getUser(), CredsUtil.tryAesDecrypt(entity.getPasswd()));
        StarResponseEntity response;
        try {
            response = poolManager.doGet(url, headers);
        } catch (Exception e) {
            log.debug("Test fe monitoring interface exists. url:{}, exception:{}", url, e.getMessage());
            return false;
        }
        return response.getData() != null;
    }

    public Object getConfigurationInfo(String type, ClusterInfoEntity entity) {

        try {
            Map<String, Object> config = starConfigClient.getConfigurationInfo(type, entity);
            return ResponseEntityBuilder.ok(JSON.toJSON(config));
        } catch (Exception e) {
            return ResponseEntityBuilder.notFound("not fount");
        }
    }
}
